package com.lagou.controller;

import com.lagou.model.LagouUser;
import com.lagou.service.CodeServcieFeign;
import com.lagou.service.ILagouUserService;
import com.lagou.tool.CommonResponse;
import com.lagou.tool.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.rmi.runtime.Log;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/user")
@Slf4j
public class UserController implements ApplicationContextAware {

    @Autowired
    @Qualifier("lagouUserServiceImpl")
    private ILagouUserService ilagouUserService;

    @Autowired
    private CodeServcieFeign codeServcieFeign;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private static ApplicationContext context;

    public static final int AVALIABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
    public static ThreadPoolExecutor executor = new ThreadPoolExecutor(AVALIABLE_PROCESSORS, AVALIABLE_PROCESSORS, 1, TimeUnit.MINUTES,
            new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.CallerRunsPolicy());


    @RequestMapping("/register/{email}/{password}/{code}")
    @ResponseBody
    public CommonResponse register(@PathVariable("email") String email, @PathVariable("password") String password, @PathVariable("code") String code) {

        if (ilagouUserService.isEmailRegister(email)) {
            return CommonResponse.FailWithMsg(1, "该邮箱已被注册了，请换个邮箱!!!");
        }

        // 校验验证码是否正确，是否超时

        CompletableFuture cf = CompletableFuture.supplyAsync(() -> {
            return  codeServcieFeign.validateCode(email, code);
        }, executor);

        String result="";
//        Object object = null;
        try {
         Object   object = cf.get();
         result = object == null ? "" : object.toString();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        if ("1".equals(result)) {
            return CommonResponse.FailWithMsg(1, "验证码错误");
        } else if ("2".equals(result)) {
            return CommonResponse.FailWithMsg(2, "验证码超时");
        } else if ("0".equals(result)) {
            // 验证验证码成功

            ilagouUserService.addUser(password, email);
            return CommonResponse.success();
        } else {
            return CommonResponse.FailWithMsg(1, "注册失败");
        }
    }


    @RequestMapping("/login/{email}/{password}")
    @ResponseBody
    public CommonResponse login(@PathVariable("email") String email, @PathVariable("password") String password) {
        // 验证用户名，密码 ，并写入token
        LagouUser lagouUser = ilagouUserService.getUserByMailAndPassword(email, password);
        if (lagouUser == null) {
            return CommonResponse.FailWithMsg(400, "登录失败");
        }
        // token合法就查询邮箱，把登录着的邮箱写到页面上
        String token = UUID.randomUUID().toString();
        HttpSession session = request.getSession();
//        try {
//            reflectSetHeader(request,"token", URLEncoder.encode(token, "UTF-8"));
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
        session.setAttribute("token", token);
        CommonResponse commonResponse = codeServcieFeign.saveToken(token, email);
        if (commonResponse.getCode() == 200) {
            return CommonResponse.successWithData(token);
        }

        return CommonResponse.Fail();
    }

    @RequestMapping("/index")
    public String index() {

        return "welcome";
    }

    @RequestMapping("/loginHtml")
    public String loginHtml() {

        return "loginHtml";
    }

    @RequestMapping("/registerHtml")
    public String registerHtml() {

        return "registerHtml";
    }

    @RequestMapping("/info/{token}")
    @ResponseBody
    public String getUserEmailByToken(@PathVariable("token") String token) {
        String token1 = WebUtil.getRequest().getHeader("token");
        log.info("header  token:{}",token1);
        if(StringUtils.isNotEmpty(token)){
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            // 中文在请求头中会变为乱码，因此要进行转化
//            try {
//                reflectSetHeader(request,"token", URLEncoder.encode(token, "UTF-8"));
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }

        }
        return codeServcieFeign.getEmailByToken(token);
    }

    @RequestMapping("/testuser")
    @ResponseBody
    public String testUser(){

        return "ok";
    }


    /**
     * 功能描述：实现往请求里加入我们的header
     * @param request request对象
     * @param key header的key
     * @param value header的值
     */
    private void reflectSetHeader(HttpServletRequest request, String key, String value){
        Class<? extends HttpServletRequest> requestClass = request.getClass();
        try {
            Field request1 = requestClass.getDeclaredField("request");
            request1.setAccessible(true);
            Object o = request1.get(request);
            Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
            coyoteRequest.setAccessible(true);
            Object o1 = coyoteRequest.get(o);
            Field headers = o1.getClass().getDeclaredField("headers");
            headers.setAccessible(true);
            MimeHeaders o2 = (MimeHeaders)headers.get(o1);
            o2.removeHeader(key);
            o2.addValue(key).setString(value);
        } catch (Exception e) {

        }
    }

    @RequestMapping("/getActiveProfile")
    @ResponseBody
    public String getActiveProfile(){

        return context.getEnvironment().getActiveProfiles()[0];
    }

    @PostConstruct
    public void init(){
        log.info("me is do.............");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (context== null) {
            context = applicationContext;
        }
    }
}
